package com.ecp.base.service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.json.JSONObject;
import org.springframework.stereotype.Repository;

import com.ecp.commons.bean.Page;
import com.ecp.commons.db.GenericServiceImpl;
import com.ecp.crm.bean.User;
import com.ecp.user.bean.PayResult;
import com.ecp.user.util.PayResultUtil;
import com.ecp.util.ArithUtil;
import com.ecp.util.HttpClientUtil;
import com.ecp.util.Util;

@Repository("userService")
public class UserServiceImpl extends GenericServiceImpl<User> implements UserService {

	protected static final Logger logger = Logger.getLogger("flight_emoney");
	private static String host = "uc.pinzhi365.com";
//	private static String host = "192.168.70.11";
	private static String port = "80";

	@Override
	public User getUserByLoginId(String loginId) throws Exception {
		String sql = "select * from crm_user where loginId = ? ";
		User user = this.getEntity(sql, new Object[] { loginId });
		return user;
	}

	private String user2xml(User user, String accountType) {
		if (user == null) {
			return "";
		}
		Document doc = DocumentHelper.createDocument();
		Element root = doc.addElement("request").addAttribute("accountType", accountType);
		Element userEl = root.addElement("user");
		userEl.addElement("id").setText(String.valueOf(user.getId()));
		userEl.addElement("loginId").setText(user.getLoginId());
		return Util.formatXmlDocument(doc);
	}

	public double getUserGeRenDeposit(User user) {
		final String accountType = "geRenDeposit";
		double amount = 0D;
		String req = user2xml(user, accountType);
		Map<String, String> params = new HashMap<String, String>();
		params.put("data", req);
		String url = String.format("http://%s:%s/services/api/account/getAccountBalance", host,
				port);
		try {
			String ret = HttpClientUtil.invokePost(url, params, "UTF-8");
			if (StringUtils.isNotEmpty(ret)) {
				// 解析响应报文
				Document doc = DocumentHelper.parseText(ret);
				Element root = doc.getRootElement();
				String response_accountType = root.attributeValue("accountType");
				if (StringUtils.equalsIgnoreCase(accountType, response_accountType)) {
					amount = new BigDecimal(root.getTextTrim()).doubleValue();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return amount;
	}

	public double getUserShopDeposit(User user) {
		final String accountType = "shopDeposit";
		double amount = 0D;
		String req = user2xml(user, accountType);
		Map<String, String> params = new HashMap<String, String>();
		params.put("data", req);
		String url = String.format("http://%s:%s/services/api/account/getAccountBalance", host,
				port);
		try {
			String ret = HttpClientUtil.invokePost(url, params, "UTF-8");
			if (StringUtils.isNotEmpty(ret)) {
				// 解析响应报文
				Document doc = DocumentHelper.parseText(ret);
				Element root = doc.getRootElement();
				String response_accountType = root.attributeValue("accountType");
				if (StringUtils.equalsIgnoreCase(accountType, response_accountType)) {
					amount = new BigDecimal(root.getTextTrim()).doubleValue();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return amount;
	}

	private String emoneyPay2xml(User user, double shopDeposit, double geRenDeposit,
			String orderAliasCode, String payPwd) {
		final String src = "GlobalSite";
		Document doc = DocumentHelper.createDocument();
		Element root = doc.addElement("request");
		Element head = root.addElement("messageHead");
		Element body = root.addElement("messageBody");

		head.addElement("id").setText(String.valueOf(user.getId()));
		head.addElement("loginId").setText(user.getLoginId());
		head.addElement("password").setText(payPwd);
		head.addElement("orderAliasCode").setText(orderAliasCode);
		head.addElement("src").setText(src);

		body.addElement("shopDeposit").setText(String.valueOf(shopDeposit));
		body.addElement("geRenDeposit").setText(String.valueOf(geRenDeposit));
		return Util.formatXmlDocument(doc);
	}

	public PayResult emoneyPay(User user, double shopDeposit, double geRenDeposit,
			String orderAliasCode, String payPwd) {
		String req = emoneyPay2xml(user, shopDeposit, geRenDeposit, orderAliasCode, payPwd);
		Map<String, String> params = new HashMap<String, String>();
		params.put("data", req);
		String url = String.format("http://%s:%s/services/api/account/emoneyPay", host, port);
		PayResult result = null;
		try {
			String ret = HttpClientUtil.invokePost(url, params, "UTF-8");
			if (StringUtils.isNotEmpty(ret)) {
				// 解析响应报文
				result = PayResultUtil.xml2PayResult(ret);
			}
		} catch (Exception e) {
			e.printStackTrace();
			result = null;
		}
		return result;
	}

	@Override
	public double getUserDeposit(int userId) {
		double deposit = 0.0D;
		try {
			String sql = "select deposit as balance from crm_user where id = ?";
			List<JSONObject> deposits = this.search(sql, new Object[] { userId }, new Page());
			if (deposits != null && deposits.size() > 0) {
				deposit = deposits.get(0).getDouble("balance");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return deposit;
	}

	private double getSubPrice(double needPrice, double userPrice) {
		double subPrice = 0D;
		try {
			if (needPrice >= userPrice) {
				subPrice = ArithUtil.sub(needPrice, userPrice);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return subPrice;
	}

	@Override
	public double useEmoney(double orderAmt, User user, String payPwd, String aliasCode) {
		double useEmoney = 0D;
		try {
			double temp = 0D;
			temp = this.getSubPrice(orderAmt, this.getUserGeRenDeposit(user));
			double geRenDeposit = 0D;
			double shopDeposit = 0D;
			if (temp > 0) {
				// 个人钱包不足支付
				geRenDeposit = this.getUserGeRenDeposit(user);
				if (this.getSubPrice(temp, this.getUserShopDeposit(user)) > 0) {
					// 店支付不足以支付
					shopDeposit = this.getUserShopDeposit(user);
				} else {
					shopDeposit = temp;
				}
			} else {
				geRenDeposit = orderAmt;
			}

			PayResult payResult = this
					.emoneyPay(user, shopDeposit, geRenDeposit, aliasCode, payPwd);
			if (payResult.getPaySuccess() == 1) {
				// 支付成功
				useEmoney = ArithUtil.add(shopDeposit, geRenDeposit);
			} else {
				// 记录出错日志
				logger.info("用户" + user.getLoginId() + "下单调用E钱包扣除接口失败，失败原因：" + payResult.getError());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return useEmoney;
	}

}
